// 播放窗口
import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:media_kit/ffi/ffi.dart';

import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:super_study_english_tool/dao/dao_user_album_media_record.dart';
import 'package:super_study_english_tool/model/model_user_album_media.dart';
import 'package:super_study_english_tool/widget/widget_player_progress_div.dart';

import '../model/model_srt_span.dart';
import '../model/model_user_album_media_record.dart';
import '../panel/panel_right.dart';
import '../service/service_user_album_media_record.dart';
import '../tools/tools_subtitle.dart';
import '../widget/widget_number_input.dart';
import '../widget/widget_subtitle.dart';

class ScreenPlayer extends StatefulWidget {
  ScreenPlayer({super.key, required this.mode, required this.media});

  // 运行模式( 0 学习 1 复习)
  int mode;

  // 媒体信息
  ModelUserAlbumMedia media;

  @override
  State<ScreenPlayer> createState() => _ScreenPlayerState();
}

class _ScreenPlayerState extends State<ScreenPlayer> {
  // 播放器
  late final _player = Player();

  // 播放器控制器
  late final _videoController = VideoController(_player);

  // mp4路径
  String? _mp4Path;

  // mp3路径
  String? _mp3Path;

  // srt路径
  String? _srtPath1;
  String? _srtPath2;

  //-------------------------------------------控制
  // 播放开关
  bool _playOn = true;

  // 正在跳回
  bool _jumpingBack = false;

  // 是否跳过空白(无字幕部分)
  bool _jumpBlank = false;

  // 正在跳空
  bool _jumpingBlank = false;

  // 跳转定时器
  Timer? _jumpTimer = null;

  // 每播放一句后等待秒数
  int _repeatWaitTime = 3;

  // 上一次跳转时间
  DateTime? _lastJumpTime = DateTime.now();

  //-------------------------------------------遮盖
  // 显示遮住块(遮住默认字幕)
  bool _showHideDiv = false;
  double _moveBarHeight = 10;
  double _moveBarBottom = 20;
  double _tmpMoveBarBottom = 0;

  //-------------------------------------------字幕
  // 所有字幕列表
  List<ModelSrtSpan> _srts = [];

  // 是否显示字幕
  bool _showSubtitle1 = false;
  bool _showSubtitle2 = false;

  // 当前字幕
  String _curSubtitle1 = "test subtitle1";
  String _curSubtitle2 = "test subtitle2";

  // 当前字幕索引
  int _curIndex = -1;

  // 最后一次对应的字幕索引
  int _lastIndex = -1;

  // 跳转字幕索引
  int _jumpToIndex = -1;

  //-------------------------------------------学习进度
  // 进度ok信息
  Map<int, int> _srtsOkMap = {};

  final ScrollController _scrollController = ScrollController();

  //-------------------------------------------用户输入
  // 键盘监听
  FocusNode _focusNode = FocusNode();

  // 当前要输入的单词列表
  List<String> _curSubtitleWords = [];
  // 用户输入的单词列表
  List<String> _inputWords = [];
  // 最近输入的内容
  String _inputLine = "";
  // 正在输入的文字
  String _inputWord = "";

  @override
  void initState() {
    super.initState();

    if (widget.media != null) {
      _mp4Path = widget.media.filePath;
      _srtPath1 = _mp4Path!.substring(0, _mp4Path!.lastIndexOf(".")) + ".srt";
      _srtPath2 = _srtPath1;
      print(_srtPath1);
    }

    play();

    readSrt();

    // 监听视频播放状态
    _player.stream.position.listen(positionListenHandle);
  }

  void positionListenHandle(Duration position) {
    // 跳转停顿过程中不刷新字幕
    if (_jumpingBack == true) return;
    if (_jumpingBlank == true) return;

    // 根据当前播放进度刷新字幕内容
    findSubtitles(position.inMilliseconds);

    // 刚jump过，不跳转
    if (_lastJumpTime != null) {
      int timeSpan = DateTime.now().millisecondsSinceEpoch - _lastJumpTime!.millisecondsSinceEpoch;
      if (timeSpan < 500) {
        return;
      }
    }

    // print("_curIndex:${_curIndex}");
    // 自动跳转处理
    if (_curIndex != -1) {
      ModelSrtSpan ss = _srts![_curIndex];
      if (_srtsOkMap[_curIndex] == null && (position.inMilliseconds - ss.endTime).abs() < 100) {
        // print("一段结尾，跳到该段开头。");
        _player.pause();
        _jumpToIndex = _curIndex;
        repeatOrConinue();
      }
    } else {
      if (_jumpBlank) {
        // print("跳转下一段");
        _jumpingBlank = true;
        _player.pause();
        nextSrt();
        Future.delayed(Duration(milliseconds: 500), () {
          _jumpingBlank = false;
        });
      }
    }
  }

  @override
  void dispose() {
    print("dispose");
    if (_jumpTimer != null) {
      _jumpTimer!.cancel();
    }
    _player.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    FocusScope.of(context).requestFocus(_focusNode);
    FocusScope.of(context).autofocus(_focusNode);

    return Scaffold(
      appBar: AppBar(
        title: Text("学习${widget.media.fileName!}"),
      ),
      body: Row(
        children: [buildLeftPanel(), buildRightPanel()],
      ),
    );
  }

  buildLeftPanel() {
    return Expanded(
        child: Column(
      children: [buildMoviePanel(), buildSubtitlePanel(), buildToolBar(), buildProgressBar(), buildInputPanel()],
    ));
  }

  buildMoviePanel() {
    return Expanded(
        child: Stack(children: [
      Video(
        controller: _videoController,
        subtitleViewConfiguration: SubtitleViewConfiguration(visible: false), // 关闭内置字幕
      ),
      Positioned(
        // top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        child: Container(
          height: _showHideDiv
              ? (_moveBarBottom + _moveBarHeight - _tmpMoveBarBottom > 0
                  ? _moveBarBottom + _moveBarHeight - _tmpMoveBarBottom
                  : 0)
              : 0,
          color: Colors.green,
        ),
      ),
      Positioned(
        // top: 0,
        left: 0,
        right: 0,
        bottom: _moveBarBottom - _tmpMoveBarBottom > 0 ? _moveBarBottom - _tmpMoveBarBottom : 0,
        child: GestureDetector(
          onVerticalDragUpdate: (e) {
            print(e);
            setState(() {
              _tmpMoveBarBottom = e.localPosition.dy;
              print("moveBarBottom:${_moveBarBottom}");
            });
          },
          onVerticalDragEnd: (e) {
            _moveBarBottom -= _tmpMoveBarBottom;
            if (_moveBarBottom < 0) {
              _moveBarBottom = 0;
            }
          },
          child: MouseRegion(
            cursor: SystemMouseCursors.resizeUpDown,
            child: Container(
              height: _showHideDiv ? _moveBarHeight : 0,
              color: Colors.blue,
            ),
          ),
        ),
      ),
    ]));
  }

  buildSubtitlePanel() {
    List<Widget> l = [];
    if (_showSubtitle1! && _srtPath1 != null) {
      l.add(WidgetSubtitle(
        height: 50,
        fontSize: 25,
        showSubtitle: _showSubtitle1,
        subtitle: _curSubtitle1,
        textColor: Colors.white,
        wrongTextColor: Colors.white,
        backgroundColor: Colors.black,
      ));
    }
    if (_showSubtitle2! && _srtPath2 != null) {
      l.add(WidgetSubtitle(
        height: 50,
        fontSize: 25,
        showSubtitle: _showSubtitle2,
        subtitle: _curSubtitle2,
        textColor: Colors.white,
        wrongTextColor: Colors.white,
        backgroundColor: Colors.black,
      ));
    }
    return Column(
      children: l,
    );
  }

// 工具栏面板
  buildToolBar() {
    return Container(
      height: 40,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextButton(
              onPressed: () {
                op("play_or_pause");
              },
              child: Text(_playOn ? "暂停" : "继续")),
          TextButton(
              onPressed: () {
                op("switch_sub1");
              },
              child: Text(!_showSubtitle1 ? "显示字幕1" : "隐藏字幕1")),
          TextButton(
              onPressed: () {
                op("switch_sub2");
              },
              child: Text(!_showSubtitle2 ? "显示字幕2" : "隐藏字幕2")),
          TextButton(
              onPressed: () {
                op("prev_srt");
              },
              child: Text("上一句")),
          TextButton(
              onPressed: () {
                op("next_srt");
              },
              child: Text("下一句")),
          // Text(srts == null ? "" : "已完成:${srtsOkMap.keys.length}/${srts!.length}"),
          SizedBox(
            width: 20,
          ),
          Text("复读等待:"),
          Material(
              child: WidgetNumberInput(
            onValueChanged: repeatWaitTimeChange,
            num: _repeatWaitTime,
          )),
          Text("秒"),
          SizedBox(
            width: 20,
          ),
          TextButton(
              onPressed: () {
                print("显示右侧栏目");
                op("show_right_panel");
              },
              child: Text("显右")),
          TextButton(
              onPressed: () {
                print("显示遮住层");
                setState(() {
                  _showHideDiv = !_showHideDiv;
                });
              },
              child: Text("显遮")),
          TextButton(
              onPressed: () {
                setState(() {
                  _jumpBlank = !_jumpBlank;
                });
              },
              child: Text(_jumpBlank ? "跳空" : "不跳空")),
          TextButton(
              onPressed: () {
                print("忽略");
                // nextSrt();
                ignoreSrt();
              },
              child: Text("忽略这句")),
          TextButton(
              onPressed: () {
                // print("忽略");
                op("test1");
              },
              child: Text("测试1"))
        ],
      ),
    );
  }

  // 进度条面板
  buildProgressBar() {
    return Container(
      width: double.infinity,
      // width: 300,
      height: (_srts == null || _srts.length == 0) ? 0 : 30,
      decoration: BoxDecoration(color: Colors.grey),
      child: (_srts == null || _srts.length == 0)
          ? null
          : (_srts.length < 20
              ? Flex(
                  direction: Axis.horizontal,
                  children: buildProgressBarDivs(),
                )
              : buildProgressBarListView()),
    );
  }

  bool _divTapDownStatus = false;
// 小于20进度条
  buildProgressBarDivs() {
    List<Widget> list = [];
    if (_srts == null) {
      Widget w = Expanded(
        flex: 1,
        child: Container(
          height: 28.0,
          color: Colors.white10,
        ),
      );
      list.add(w);
    } else {
      for (int i = 0; i < _srts!.length; i++) {
        Widget w = Expanded(
          flex: 1,
          child: WidgetPlayerProgressDiv(
              srtsOkMap: _srtsOkMap,
              i: i,
              curIndex: _curIndex,
              onTap: () {
                jumpTo(i);
              }),
        );
        list.add(w);
      }
    }
    return list;
  }

// 大于20进度条
  buildProgressBarListView() {
    // print("buildProgressBarListView()");
    return Container(
      child: Row(
        children: [
          SizedBox(
            width: 50,
            height: 50,
            child: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                op("scroll_left");
              },
            ),
          ),
          Expanded(
            child: SizedBox(
              height: 50,
              child: ListView.builder(
                  controller: _scrollController,
                  scrollDirection: Axis.horizontal,
                  itemCount: _srts.length,
                  itemBuilder: (BuildContext context, int i) {
                    return WidgetPlayerProgressDiv(
                        srtsOkMap: _srtsOkMap,
                        i: i,
                        curIndex: _curIndex,
                        onTap: () {
                          jumpTo(i);
                        });
                  }),
            ),
          ),
          SizedBox(
            width: 50,
            height: 50,
            child: IconButton(
              icon: Icon(Icons.arrow_forward),
              onPressed: () {
                op("scroll_right");
              },
            ),
          ),
        ],
      ),
    );
  }

  buildInputPanel() {
    return Container(
      height: 150,
      child: Column(
        children: [
          WidgetSubtitle(
            height: 50,
            fontSize: 25,
            showSubtitle: true,
            subtitle: _curSubtitle1,
            textColor: Colors.white,
            inputWords: _inputWords,
            // 和背景色一样
            wrongTextColor: Colors.deepPurpleAccent,
            backgroundColor: Colors.deepPurpleAccent,
            undLineColor: Colors.white,
            showUnderLine: true,
          ),
          Container(
            decoration: BoxDecoration(color: Colors.lightBlueAccent),
            width: double.infinity,
            alignment: Alignment.center,
            height: 50,
            child: Text(
              _inputLine,
              style: TextStyle(fontSize: 36, color: Colors.white, decoration: TextDecoration.none),
            ),
          ),
          KeyboardListener(
            focusNode: _focusNode,
            autofocus: true, // 要开启自动焦点
            onKeyEvent: (KeyEvent event) {
              print("focusNode2:${event},${event.runtimeType}");

              // event.runtimeType == KeyUpEvent
              // event.runtimeType == KeyRepeatEvent
              print("event.character:${event.character}");
              print("event.logicalKey.keyLabel:${event.logicalKey.keyLabel}");
              print("event.logicalKey.debugName:${event.physicalKey.debugName}");
              if (event.runtimeType == KeyUpEvent) {
                if (event.logicalKey.keyLabel == "Enter" || event.physicalKey.debugName == "Space") {
                  setState(() {
                    _inputLine = _inputWord.trim();
                    _inputWord = "";
                    checkInputSubtitle();
                  });
                }
              } else if (event.runtimeType == KeyDownEvent) {
                if (event.logicalKey.keyLabel == "Arrow Up") {
                  print("向上键");
                  setState(() {
                    _inputWord = _inputLine;
                  });
                } else if (event.logicalKey.keyLabel == "Backspace") {
                  if (_inputWord.length > 0) {
                    setState(() {
                      print(_inputWord);
                      if (_inputWord.length == 1) {
                        _inputWord = "";
                      } else {
                        _inputWord = _inputWord.substring(0, _inputWord.length - 1);
                      }
                      print(_inputWord);
                    });
                  }
                } else if (event.character != null) {
                  setState(() {
                    _inputWord += event.character!;
                  });
                }
              }
            },
            child: Container(
              decoration: BoxDecoration(color: Colors.green),
              width: double.infinity,
              alignment: Alignment.center,
              height: 50,
              child: Text(
                _inputWord,
                style: TextStyle(fontSize: 36, color: Colors.white, decoration: TextDecoration.none),
              ),
            ),
          ),
        ],
      ),
    );
  }

  buildRightPanel() {
    return Container(
      width: 30,
      child: Placeholder(),
    );
  }

  op(opStr) {
    print("${opStr}");
    switch (opStr) {
      case "play_or_pause":
        print("播放或暂停");
        _playOn = !_playOn;
        if (_playOn) {
          _player.play();
        } else {
          _player.pause();
        }
        setState(() {});
        break;
      case "switch_sub1":
        print("switch_sub1");
        setState(() {
          _showSubtitle1 = !_showSubtitle1;
          if (_showSubtitle1) {
            saveWrongSentence();
          }
        });
        break;
      case "switch_sub2":
        print("switch_sub2");
        setState(() {
          _showSubtitle2 = !_showSubtitle2;
        });
        break;
      case "prev_srt":
        prevSrt();
        break;
      case "next_srt":
        nextSrt();
        break;
      case "scroll_left":
        scrollLeft();
        break;
      case "scroll_right":
        scrollRight();
        break;
    }
  }

  // 播放
  void play() {
    if (_mp4Path != null) {
      _player.open(Media(_mp4Path!));
    }
    if (_mp3Path != null) {
      _player.open(Media(_mp3Path!));
    }
  }

  // 修改等待时间
  void repeatWaitTimeChange(int t) {
    print("数字改变:${t}");
    this._repeatWaitTime = t;
  }

  // 读取字幕
  Future<void> readSrt() async {
    if (_srtPath1 != null) {
      File file = File(_srtPath1!);
      String content = file.readAsStringSync();
      print('读取到字幕1:' + content);
      _srts = ToolsSubtitle.handleSrtContent(content);
    }

    initOkMap();
  }

  initOkMap() {
    // 查询
    List<ModelUserAlbumMediaRecord> records =
        DaoUserAlbumMediaRecord.findAllByMediaId(widget.media.userAlbumId!, widget.media.id!);
    print(records);

    if (_srts != null && _srts.length > 0) {
      for (int i = 0; i < _srts.length; i++) {
        for (int j = 0; j < records.length; j++) {
          ModelUserAlbumMediaRecord r = records[j];
          if (r.sentenceId == i) {
            if (r.status == 1) {
              _srtsOkMap[i] = 1;
            } else if (r.status == 0) {
              if (!r.needReview()) {
                _srtsOkMap[i] = 1;
              }
              // _srtsOkMap[i] = r.needReview() ? 0 : 1;
            } else if (r.status == -2) {
              _srtsOkMap[i] = 1;
            }
          }
        }
      }
    }
  }

  // 查找字幕
  void findSubtitles(int curTime) {
    // 1. 字幕还没加载完成,直接退出s
    if (_srts == null) return;

    int tmpIndex = -1;
    String tmpSubTitle = "";

    // 还没加载过任何字幕，从头开始找
    int startFind = 0;

    // 加载过，先判断是否在之前范围内
    if (_lastIndex != -1) {
      ModelSrtSpan ss = _srts![_lastIndex];
      if (ss.startTime <= curTime) {
        if (ss.endTime >= curTime) {
          // 在范围内
          startFind = _lastIndex;
        } else {
          // 往后找
          startFind = _curIndex + 1;
        }
      } else {
        // 从头找
        startFind = 0;
      }
    }

    for (int i = startFind; i < _srts!.length; i++) {
      ModelSrtSpan ss = _srts![i];
      if (ss.startTime <= curTime) {
        if (ss.endTime >= curTime) {
          // 在范围内
          tmpIndex = i;
          tmpSubTitle = ss.content;
          _lastIndex = i;
          break;
        }
      } else {
        // 结束查找
        break;
      }
    }
    // print("${tmpIndex}:${tmpSubTitle}");
    if (_curIndex != tmpIndex) {
      setState(() {
        _curIndex = tmpIndex;
        _curSubtitle1 = tmpSubTitle;
        print("${_curIndex}:${_curSubtitle1}");
        refreshCurSubtitleWords();
      });
    }
    // print("当前字幕:${curIndex},${curSubtitle1}");
  }

  void prevSrt() {
    print("前一句");
    if (_srts == null) return;
    // 停止自动跳转
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }

    print("curIndex = ${_curIndex}");
    int jumpIndex = -1;
    if (_curIndex > 0) {
      jumpIndex = _curIndex - 1;
    } else if (_curIndex == 0) {
      jumpIndex = 0;
    } else {
      if (_lastIndex > -1) {
        jumpIndex = _lastIndex;
      } else {
        jumpIndex = 0;
      }
    }
    if (jumpIndex != -1) {
      _player.seek(Duration(milliseconds: _srts![jumpIndex].startTime));
      _lastJumpTime = DateTime.now();
      _player.play();
    }
  }

  // 后一句
  void nextSrt() {
    print("后一句");
    if (_srts == null) return;
    // 停止自动跳转
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }
    print("curIndex = ${_curIndex}");

    int jumpIndex = -1;
    if (_curIndex > -1) {
      jumpIndex = _curIndex + 1;
    } else {
      jumpIndex = _lastIndex + 1;
    }
    if (jumpIndex >= _srts.length) {
      jumpIndex = _srts.length - 1;
    }
    print("跳转${jumpIndex}");
    if (jumpIndex != _srts!.length) {
      print("跳转${_srts![jumpIndex].startTime}");
      _player.seek(Duration(milliseconds: _srts![jumpIndex].startTime));
      _lastJumpTime = DateTime.now();
      _player.play();
    }
  }

  void jumpTo(i) {
    _jumpingBack = false;
    if (_jumpTimer != null && _jumpTimer!.isActive) {
      _jumpTimer!.cancel();
    }
    _player.seek(Duration(milliseconds: _srts![i].startTime));
    _lastJumpTime = DateTime.now();
    _player.play();
  }

  void repeatOrConinue() {
    ModelSrtSpan srt = _srts![_jumpToIndex];
    // print("隔${_repeatWaitTime}秒跳转到${srt.startTime}");
    _jumpingBack = true;

    _jumpTimer = Timer(Duration(milliseconds: _repeatWaitTime * 1000), () {
      // 如果已完成，则继续播放，如果未完成，则跳回
      if (_jumpingBack && _playOn) {
        if (_srtsOkMap[_jumpToIndex] == null) {
          // 如果还没有完成，则跳回
          _player.seek(Duration(milliseconds: srt.startTime + 3));
          _lastJumpTime = DateTime.now();
        }
        _player.play();
        _jumpingBack = false;
      }
      _jumpTimer!.cancel();
    });
  }

  void scrollLeft() {
    double p = _scrollController.offset;
    p -= 200;
    if (p < 0) {
      p = 0;
    }
    _scrollController.animateTo(p, duration: Duration(milliseconds: 300), curve: Curves.easeOut);
  }

  void scrollRight() {
    double p = _scrollController.offset;
    p += 200;
    if (p < 0) {
      p = 0;
    }
    _scrollController.animateTo(p, duration: Duration(milliseconds: 300), curve: Curves.easeOut);
  }

  // 检测输入内容是否正确
  void checkInputSubtitle() {
    print("checkInputSubtitle() ");
    print(_curSubtitleWords);
    // 比较当前输入的inputLine
    // 和当前的完整字幕curSubtitle1
    // 如果符合 则放入inputWords
    if (_curSubtitleWords.contains(_inputLine)) {
      _inputWords.add(_inputLine);
      print("符合,放入！");

      List<bool> checkList = [];
      List<bool> usedList = [];
      for (int j = 0; j < _inputWords.length; j++) {
        usedList.add(false);
      }

      for (int i = 0; i < _curSubtitleWords.length; i++) {
        checkList.add(false);
        for (int j = 0; j < _inputWords.length; j++) {
          if (usedList[j] == false && _curSubtitleWords[i].toLowerCase() == _inputWords[j]) {
            checkList[i] = true;
            usedList[j] = true;
            break;
          }
        }
      }
      bool ok = true;
      for (int i = 0; i < _curSubtitleWords.length; i++) {
        if (checkList[i] == false) {
          ok = false;
        }
      }
      if (ok) {
        _srtsOkMap[_curIndex] = 1;
        // saveToDb(true);

        // showToast("太棒了！", context: context);

        saveRightSentence();

        _showSubtitle1 = false;
      }
    }
  }

  void saveRightSentence() {
    ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
    r.albumId = widget.media.userAlbumId;
    r.mediaId = widget.media.id;
    r.sentenceId = _curIndex;
    ModelSrtSpan span = _srts[_curIndex];
    r.sentence = span.content; // ?
    r.startTime = span.startTime; // ?
    r.endTime = span.endTime; // ?
    // r.status = 1;
    ServiceUserAlbumMediaRecord.saveRight(r);
  }

  void saveWrongSentence() {
    ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
    r.albumId = widget.media.userAlbumId;
    r.mediaId = widget.media.id;
    r.sentenceId = _curIndex;
    ModelSrtSpan span = _srts[_curIndex];
    r.sentence = span.content; // ?
    r.startTime = span.startTime; // ?
    r.endTime = span.endTime; // ?
    // r.status = 1;
    ServiceUserAlbumMediaRecord.saveWrong(r);
  }

  // 刷新当前要输入的字符串列表
  void refreshCurSubtitleWords() {
    _curSubtitleWords = ToolsSubtitle.strToWords(_curSubtitle1);
    _inputWords = [];
    print(_curSubtitleWords);
  }

  void ignoreSrt() {
    _srtsOkMap[_curIndex] = 1;
    // 忽略当前一句
    ModelUserAlbumMediaRecord r = new ModelUserAlbumMediaRecord();
    r.albumId = widget.media.userAlbumId;
    r.mediaId = widget.media.id;
    r.sentenceId = _curIndex;
    ModelSrtSpan span = _srts[_curIndex];
    r.sentence = span.content; // ?
    r.startTime = span.startTime; // ?
    r.endTime = span.endTime;
    ServiceUserAlbumMediaRecord.saveIgnore(r);
  }
}
